package com.lovesher.payment.service.plugin.apple;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lovesher.payment.common.enums.NotifyMethod;
import com.lovesher.payment.common.enums.PayStatus;
import com.lovesher.payment.common.resposity.bean.AccountRechargeDTO;
import com.lovesher.payment.common.resposity.bean.PaymentSerial;
import com.lovesher.payment.service.resposity.bean.PaymentInterface;
import com.lovesher.payment.service.resposity.dao.PaymentDao;
import com.lovesher.payment.service.resposity.dao.PaymentSerialDao;
import com.lovesher.payment.service.resposity.mapper.PluginConfigAttributeMapper;

/**
 * @Title: AliPayPlugin.java
 * 
 * @Package com.business.pay.service.plugin.apple
 * 
 * @Description: 苹果支付插件
 * 
 * @version V1.0
 */
@Component("appleAppPayPlugin")
public class AppleAppPayPlugin extends PaymentInterface {

	private static Log log = LogFactory.getLog(AppleAppPayPlugin.class);

	
	private String bundleId = "com.yingmi.zhangyuge";
	
	@Resource
	private PluginConfigAttributeMapper pluginConfigAttributeMapper;

	@Resource
	private PaymentSerialDao paymentSerialDao;
	
	@Resource
	private PaymentDao paymentDao;

	@Override
	public String getName() {
		return "苹果支付";
	}

	@Override
	public String getVersion() {
		return "1.0";
	}

	@Override
	public String getAuthor() {
		return "tupx";
	}

	/**
	 * 获取网址
	 * 
	 * @return 网址
	 */
	@Override
	public String getSiteUrl() {
		return "https://sandbox.itunes.apple.com/verifyReceipt";
	}

	/**
	 * 获取请求URL
	 * 
	 * @return 请求URL
	 */
	@Override
	public String getRequestUrl() {
		return "https://buy.itunes.apple.com/verifyReceipt";
	}

	/**
	 * 获取请求方法
	 * 
	 * @return 请求方法
	 */
	@Override
	public RequestMethod getRequestMethod() {
		return RequestMethod.post;
	}

	/**
	 * 获取请求字符编码
	 * 
	 * @return 请求字符编码
	 */
	@Override
	public String getRequestCharset() {
		return "UTF-8";
	}
	
	/**
	 * 获取请求参数
	 * 
	 * @param sn
	 *            编号
	 * @param description
	 *            描述
	 * @param request
	 *            httpServletRequest
	 * @return 请求参数
	 */
	@Override
	public Map<String, String> getParameterMap(AccountRechargeDTO accountRechargeDTO, String serialSn) {
		log.info("appleAppPayPlugin getParameter start..."+JSONObject.toJSONString(accountRechargeDTO)+",serialSn"+serialSn);
		// 数据库中获取支付相关参数
		Map<String, String> resultMap = new HashMap<String, String>();
		resultMap.put("success", "false");
		String result = sendHttpsCoon(getRequestUrl(), accountRechargeDTO.getReceipt());
		log.info("result:" + result);
		if(null == result){
			return resultMap;
		}
		JSONObject json =  JSON.parseObject(result, JSONObject.class);
		Integer status = json.getInteger("status");
		if(status == 21007){//沙盒测试
			result = sendHttpsCoon(getSiteUrl(), accountRechargeDTO.getReceipt());
			json =  JSON.parseObject(result, JSONObject.class);
			status = json.getInteger("status");
		}
		if(status == 0){
			JSONObject receipt = json.getJSONObject("receipt");
			String bundle_id = receipt.getString("bundle_id");
			String receipt_creation_date_ms = receipt.getString("receipt_creation_date_ms");
			//60分钟内
			Long timeStart = Long.parseLong(receipt_creation_date_ms) - 60 * 60 * 1000;
			Long timeEnd = Long.parseLong(receipt_creation_date_ms) + 60 * 60 * 1000;
			Long curr = System.currentTimeMillis();
			if(curr<timeStart || curr>timeEnd){
				log.error("receipt timeout error：" + accountRechargeDTO.getReceipt());
				resultMap.put("success", "false");
				resultMap.put("message", "receipt timeout");
				return resultMap;
			}
			if(!bundle_id.equals(bundleId)){
				log.error("bundleId error：" + accountRechargeDTO.getReceipt());
				log.error("bundleId error：" + bundle_id);
				resultMap.put("success", "false");
				resultMap.put("message", "bundleId error");
				return resultMap;
			}
			PaymentSerial paymentSerial = this.paymentSerialDao.findByOrderSn(serialSn, accountRechargeDTO.getUserId());
			if (paymentSerial.getStatus() == PayStatus.INIT.getValue()){
				PaymentSerial npaymentSerial = new PaymentSerial();
				npaymentSerial.setId(paymentSerial.getId());
				npaymentSerial.setStatus(PayStatus.SUCCESS.getValue());
				this.paymentSerialDao.update(npaymentSerial);
			}
			resultMap.put("success", "true");
		}
		log.info("result:" + status);
		return resultMap;
	}

	/**
	 * 构造签名
	 * 
	 * @param params
	 * @param pluginConfigMap 
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public String createSign(Map<String, String> params, Map<String, Object> pluginConfigMap) {
		return null;
	}

	/**
	 * 验证通知是否合法
	 * 
	 * @param sn
	 *            编号
	 * @param notifyMethod
	 *            通知方法
	 * @param request
	 *            httpServletRequest
	 * @return 通知是否合法
	 */
	@Override
	public Map<String, Object> verifyNotify(String sn, NotifyMethod notifyMethod, HttpServletRequest request,
			PaymentSerial paymentSerial) {
				return null;
	}

	/**
	 * 获取通知返回消息
	 * 
	 * @param sn
	 *            编号
	 * @param notifyMethod
	 *            通知方法
	 * @param request
	 *            httpServletRequest
	 * @return 通知返回消息
	 */
	@Override
	public String getNotifyMessage(String sn, NotifyMethod notifyMethod, HttpServletRequest request) {
		return null;
		
	}

	/**
	 * 获取超时时间
	 * 
	 * @return 超时时间
	 */
	@Override
	public Integer getTimeout() {
		return 21600;
	}

	/**
	 * 充值支付回调验证成功处理方法
	 * 
	 * @param request
	 */
	@Override
	public void paySucess(PaymentSerial paymentSerial, String returnText, PayStatus payStatus,
			HttpServletRequest request) {
	}

	@Override
	public Boolean queryOrderResult(PaymentSerial paymentSerial) {
		return null;
	}
	
	/**
	 * 重写X509TrustManager
	 */
	private static TrustManager myX509TrustManager = new X509TrustManager() {
		
		@Override
		public X509Certificate[] getAcceptedIssuers() {
			return null;
		}
		
		@Override
		public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
			
		}
		
		@Override
		public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
			
		}
	};
	
	/**
	 * 发送请求
	 * @param url
	 * @param strings
	 * @return
	 * {"receipt":{"original_purchase_date_pst":"2016-04-28 03:18:49 America/Los_Angeles", "purchase_date_ms":"1461838729285", "unique_identifier":"d4e721ec67ef2feca7fbdbd25a45cfb37e10ea7b", "original_transaction_id":"1000000208620470", "bvrs":"1.1", "transaction_id":"1000000208620470", "quantity":"1", "unique_vendor_identifier":"8E19EEC4-33D7-4536-B62E-112BAC68EECD", "item_id":"1108798151", "product_id":"1244", "purchase_date":"2016-04-28 10:18:49 Etc/GMT", "original_purchase_date":"2016-04-28 10:18:49 Etc/GMT", "purchase_date_pst":"2016-04-28 03:18:49 America/Los_Angeles", "bid":"com.doctorHys", "original_purchase_date_ms":"1461838729285"}, "status":0}

	 */
	private static String sendHttpsCoon(String url, String code){
		if(url.isEmpty()){
			return null;
		}
		try {
			//设置SSLContext
			SSLContext ssl = SSLContext.getInstance("SSL");
			ssl.init(null, new TrustManager[]{myX509TrustManager}, null);
			//打开连接
			HttpsURLConnection conn = (HttpsURLConnection) new URL(url).openConnection();
			//设置套接工厂
			conn.setSSLSocketFactory(ssl.getSocketFactory());
			//加入数据
			conn.setRequestMethod("POST");
			conn.setDoOutput(true);
			conn.setRequestProperty("Content-type","application/json");
	        
	        JSONObject obj = new JSONObject();
	        obj.put("receipt-data", code);
	        
	        BufferedOutputStream buffOutStr = new BufferedOutputStream(conn.getOutputStream());
	        buffOutStr.write(obj.toString().getBytes());
	        buffOutStr.flush();
	        buffOutStr.close();
	        
	        //获取输入流
	        BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
	        
	        String line = null;
	        StringBuffer sb = new StringBuffer();
	        while((line = reader.readLine())!= null){
	        	sb.append(line);
	        }
	        return sb.toString();
		
		} catch (Exception e) {
			return null;
		}
	}
	
	public static void main(String[] args) {
		String code = "ewoJInNpZ25hdHVyZSIgPSAiQXAzbjVUZmQrVXIvQmFrTEU3VG9Dc3NOSGdxbmI2dnlrM0RLZlFxcnBxQStLV1AzVHVkZDN2N2w0OUEyc2NVY1g2cWNDeEx3bHAzR2RKMG9Ma3IzRzdTaEZFYU5UeTBrL25hRTNoWUIxY0kxajFGM1ppSmxTVC9kL1VDN0ZFY1BUMjR2SUFFZDE2WXFOdHNqWUpNYmJQVGRRR3g4NitFZWlDR21mVDJKS0VrK0FBQURWekNDQTFNd2dnSTdvQU1DQVFJQ0NCdXA0K1BBaG0vTE1BMEdDU3FHU0liM0RRRUJCUVVBTUg4eEN6QUpCZ05WQkFZVEFsVlRNUk13RVFZRFZRUUtEQXBCY0hCc1pTQkpibU11TVNZd0pBWURWUVFMREIxQmNIQnNaU0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVURXpNREVHQTFVRUF3d3FRWEJ3YkdVZ2FWUjFibVZ6SUZOMGIzSmxJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNU1CNFhEVEUwTURZd056QXdNREl5TVZvWERURTJNRFV4T0RFNE16RXpNRm93WkRFak1DRUdBMVVFQXd3YVVIVnlZMmhoYzJWU1pXTmxhWEIwUTJWeWRHbG1hV05oZEdVeEd6QVpCZ05WQkFzTUVrRndjR3hsSUdsVWRXNWxjeUJUZEc5eVpURVRNQkVHQTFVRUNnd0tRWEJ3YkdVZ1NXNWpMakVMTUFrR0ExVUVCaE1DVlZNd2daOHdEUVlKS29aSWh2Y05BUUVCQlFBRGdZMEFNSUdKQW9HQkFNbVRFdUxnamltTHdSSnh5MW9FZjBlc1VORFZFSWU2d0Rzbm5hbDE0aE5CdDF2MTk1WDZuOTNZTzdnaTNvclBTdXg5RDU1NFNrTXArU2F5Zzg0bFRjMzYyVXRtWUxwV25iMzRucXlHeDlLQlZUeTVPR1Y0bGpFMU93QytvVG5STStRTFJDbWVOeE1iUFpoUzQ3VCtlWnRERWhWQjl1c2szK0pNMkNvZ2Z3bzdBZ01CQUFHamNqQndNQjBHQTFVZERnUVdCQlNKYUVlTnVxOURmNlpmTjY4RmUrSTJ1MjJzc0RBTUJnTlZIUk1CQWY4RUFqQUFNQjhHQTFVZEl3UVlNQmFBRkRZZDZPS2RndElCR0xVeWF3N1hRd3VSV0VNNk1BNEdBMVVkRHdFQi93UUVBd0lIZ0RBUUJnb3Foa2lHOTJOa0JnVUJCQUlGQURBTkJna3Foa2lHOXcwQkFRVUZBQU9DQVFFQWVhSlYyVTUxcnhmY3FBQWU1QzIvZkVXOEtVbDRpTzRsTXV0YTdONlh6UDFwWkl6MU5ra0N0SUl3ZXlOajVVUllISytIalJLU1U5UkxndU5sMG5rZnhxT2JpTWNrd1J1ZEtTcTY5Tkluclp5Q0Q2NlI0Szc3bmI5bE1UQUJTU1lsc0t0OG9OdGxoZ1IvMWtqU1NSUWNIa3RzRGNTaVFHS01ka1NscDRBeVhmN3ZuSFBCZTR5Q3dZVjJQcFNOMDRrYm9pSjNwQmx4c0d3Vi9abEwyNk0ydWVZSEtZQ3VYaGRxRnd4VmdtNTJoM29lSk9PdC92WTRFY1FxN2VxSG02bTAzWjliN1BSellNMktHWEhEbU9Nazd2RHBlTVZsTERQU0dZejErVTNzRHhKemViU3BiYUptVDdpbXpVS2ZnZ0VZN3h4ZjRjemZIMHlqNXdOelNHVE92UT09IjsKCSJwdXJjaGFzZS1pbmZvIiA9ICJld29KSW05eWFXZHBibUZzTFhCMWNtTm9ZWE5sTFdSaGRHVXRjSE4wSWlBOUlDSXlNREUyTFRBMExUSTRJREF6T2pFNE9qUTVJRUZ0WlhKcFkyRXZURzl6WDBGdVoyVnNaWE1pT3dvSkluVnVhWEYxWlMxcFpHVnVkR2xtYVdWeUlpQTlJQ0prTkdVM01qRmxZelkzWldZeVptVmpZVGRtWW1SaVpESTFZVFExWTJaaU16ZGxNVEJsWVRkaUlqc0tDU0p2Y21sbmFXNWhiQzEwY21GdWMyRmpkR2x2YmkxcFpDSWdQU0FpTVRBd01EQXdNREl3T0RZeU1EUTNNQ0k3Q2draVluWnljeUlnUFNBaU1TNHhJanNLQ1NKMGNtRnVjMkZqZEdsdmJpMXBaQ0lnUFNBaU1UQXdNREF3TURJd09EWXlNRFEzTUNJN0Nna2ljWFZoYm5ScGRIa2lJRDBnSWpFaU93b0pJbTl5YVdkcGJtRnNMWEIxY21Ob1lYTmxMV1JoZEdVdGJYTWlJRDBnSWpFME5qRTRNemczTWpreU9EVWlPd29KSW5WdWFYRjFaUzEyWlc1a2IzSXRhV1JsYm5ScFptbGxjaUlnUFNBaU9FVXhPVVZGUXpRdE16TkVOeTAwTlRNMkxVSTJNa1V0TVRFeVFrRkROamhGUlVORUlqc0tDU0p3Y205a2RXTjBMV2xrSWlBOUlDSXhNalEwSWpzS0NTSnBkR1Z0TFdsa0lpQTlJQ0l4TVRBNE56azRNVFV4SWpzS0NTSmlhV1FpSUQwZ0ltTnZiUzVrYjJOMGIzSkllWE1pT3dvSkluQjFjbU5vWVhObExXUmhkR1V0YlhNaUlEMGdJakUwTmpFNE16ZzNNamt5T0RVaU93b0pJbkIxY21Ob1lYTmxMV1JoZEdVaUlEMGdJakl3TVRZdE1EUXRNamdnTVRBNk1UZzZORGtnUlhSakwwZE5WQ0k3Q2draWNIVnlZMmhoYzJVdFpHRjBaUzF3YzNRaUlEMGdJakl3TVRZdE1EUXRNamdnTURNNk1UZzZORGtnUVcxbGNtbGpZUzlNYjNOZlFXNW5aV3hsY3lJN0Nna2liM0pwWjJsdVlXd3RjSFZ5WTJoaGMyVXRaR0YwWlNJZ1BTQWlNakF4Tmkwd05DMHlPQ0F4TURveE9EbzBPU0JGZEdNdlIwMVVJanNLZlE9PSI7CgkiZW52aXJvbm1lbnQiID0gIlNhbmRib3giOwoJInBvZCIgPSAiMTAwIjsKCSJzaWduaW5nLXN0YXR1cyIgPSAiMCI7Cn0=";
		System.out.println(sendHttpsCoon("https://buy.itunes.apple.com/verifyReceipt", code));
	}

}
